namespace Xmef.Engine
{
    using System;
    using Xmef.Interfaces;
    using Xmef.Library;
    using Xmef.Serializer;

    [Serializable]
    public class Property : PluginIdentity, IProperty, IPluginIdentity, ICompatible<Property>
    {
        private Property _instance;
        private string _name;
        private Type _type;
        private string _value;
        public static readonly IXmlRuntimeFormatter Formatter = new XmlFormatter();

        public Property()
        {
        }

        public Property(Property property)
        {
            this._instance = property;
        }

        public Property(Type type, string name, string value)
        {
            this._type = type;
            this._name = name;
            this._value = value;
        }

        public void Assign(Property obj)
        {
            this._instance = obj._instance;
            this._type = obj._type;
            this._name = obj._name;
            this._value = obj._value;
        }

        public static Property Create<T>(string propertyName)
        {
            return new Property(typeof(Property<T>), propertyName, PropertyConverter.ConvertToString<T>(default(T)));
        }

        public static Property Create<T>(string propertyName, T defaultValue)
        {
            return new Property(typeof(Property<T>), propertyName, PropertyConverter.ConvertToString<T>(defaultValue));
        }

        public static Property Create<T>(string propertyName, T defaultValue, IPropertyConverter<T> converter)
        {
            return new Property(typeof(Property<T>), propertyName, converter.ConvertToString(defaultValue));
        }

        public string Name
        {
            get
            {
                if (this._instance != null)
                {
                    return this._instance._name;
                }
                return this._name;
            }
            set
            {
                if (this._instance != null)
                {
                    this._instance._name = value;
                }
                else
                {
                    this._name = value;
                }
            }
        }

        public string Value
        {
            get
            {
                if (this._instance != null)
                {
                    return this._instance._value;
                }
                return this._value;
            }
            set
            {
                if (this._instance != null)
                {
                    this._instance._value = value;
                }
                else
                {
                    this._value = value;
                }
            }
        }

        private class XmlFormatter : XmlTypeSerializer<Property>
        {
            public override void AddOverrides(IXmlTypeFormatter formatter)
            {
                AddType(formatter, "property");
                AddElement(formatter, "Name", "name");
                AddElement(formatter, "Value", "value");
            }
        }
    }
}

